Shootdown TLB entries across all VCPUs for SMP shadow mode.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 24 Nov 2005 15:47:44 +0000 (16:47 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 24 Nov 2005 15:47:44 +0000 (16:47 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/shadow.c
xen/arch/x86/shadow32.c
xen/include/asm-x86/shadow.h

index c8ec7695960826229adeebd34979804676745025..b33950871169ec2b7a0aede656b4ab42f7a76f23 100644 (file)
@@ -1757,6 +1757,7 @@ static void sync_all(struct domain *d)
     struct out_of_sync_entry *entry;
     int need_flush = 0;
     l1_pgentry_t *ppte, opte, npte;
+    cpumask_t other_vcpus_mask;
 
     perfc_incrc(shadow_sync_all);
 
@@ -1789,23 +1790,15 @@ static void sync_all(struct domain *d)
         unmap_domain_page(ppte);
     }
 
-    // XXX mafetter: SMP
-    //
-    // With the current algorithm, we've gotta flush all the TLBs
-    // before we can safely continue.  I don't think we want to
-    // do it this way, so I think we should consider making
-    // entirely private copies of the shadow for each vcpu, and/or
-    // possibly having a mix of private and shared shadow state
-    // (any path from a PTE that grants write access to an out-of-sync
-    // page table page needs to be vcpu private).
-    //
-#if 0 // this should be enabled for SMP guests...
-    flush_tlb_mask(cpu_online_map);
-#endif
+    /* Other VCPUs mustn't use the revoked writable mappings. */
+    other_vcpus_mask = d->cpumask;
+    cpu_clear(smp_processor_id(), other_vcpus_mask);
+    flush_tlb_mask(other_vcpus_mask);
+
+    /* Flush ourself later. */
     need_flush = 1;
 
-    // Second, resync all L1 pages, then L2 pages, etc...
-    //
+    /* Second, resync all L1 pages, then L2 pages, etc... */
     need_flush |= resync_all(d, PGT_l1_shadow);
 
 #if CONFIG_PAGING_LEVELS == 2
index 5636840f7078f1c02d9a581cf26fa4a80db97ed3..8a0e81b7076cb29a7c015b7db46325f124926088 100644 (file)
@@ -2554,6 +2554,7 @@ void __shadow_sync_all(struct domain *d)
     struct out_of_sync_entry *entry;
     int need_flush = 0;
     l1_pgentry_t *ppte, opte, npte;
+    cpumask_t other_vcpus_mask;
 
     perfc_incrc(shadow_sync_all);
 
@@ -2586,23 +2587,15 @@ void __shadow_sync_all(struct domain *d)
         unmap_domain_page(ppte);
     }
 
-    // XXX mafetter: SMP
-    //
-    // With the current algorithm, we've gotta flush all the TLBs
-    // before we can safely continue.  I don't think we want to
-    // do it this way, so I think we should consider making
-    // entirely private copies of the shadow for each vcpu, and/or
-    // possibly having a mix of private and shared shadow state
-    // (any path from a PTE that grants write access to an out-of-sync
-    // page table page needs to be vcpu private).
-    //
-#if 0 // this should be enabled for SMP guests...
-    flush_tlb_mask(cpu_online_map);
-#endif
+    /* Other VCPUs mustn't use the revoked writable mappings. */
+    other_vcpus_mask = d->cpumask;
+    cpu_clear(smp_processor_id(), other_vcpus_mask);
+    flush_tlb_mask(other_vcpus_mask);
+
+    /* Flush ourself later. */
     need_flush = 1;
 
-    // Second, resync all L1 pages, then L2 pages, etc...
-    //
+    /* Second, resync all L1 pages, then L2 pages, etc... */
     need_flush |= resync_all(d, PGT_l1_shadow);
     if ( shadow_mode_translate(d) )
         need_flush |= resync_all(d, PGT_hl2_shadow);
index 84ad6a1a94b430a0ef6cae383012704db0917df4..eeee01107ff637187c8fa56fd625fe8102bbf31e 100644 (file)
@@ -596,8 +596,8 @@ update_hl2e(struct vcpu *v, unsigned long va)
         if ( need_flush )
         {
             perfc_incrc(update_hl2e_invlpg);
-            // SMP BUG???
-            local_flush_tlb_one(&linear_pg_table[l1_linear_offset(va)]);
+            flush_tlb_one_mask(v->domain->cpumask,
+                               &linear_pg_table[l1_linear_offset(va)]);
         }
     }
 }